package cn.xiaolang.function.reflex;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import cn.xiaolang.domain.Member;

/**
 * 反射的使用 
 */
public class ReflexStart {

	@SuppressWarnings("rawtypes")
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, FileNotFoundException, IOException {
		/**
		 * 1.利用每个对象的getClass方法，获取Class对象
		 */
		Member member = new Member();
		Class class1 = member.getClass();
		System.out.println(class1);
		/**
		 * 2.根据每个类的.class属性，获取Class对象
		 */
		Class class2 = Member.class;
		System.out.println(class2);
		/**
		 * 3.根据类所在的包全名，用Class.forName获取Class对象
		 */
		Class class3 = Class.forName("cn.xiaolang.domain.Member");
		System.out.println(class3);
		Properties properties = new Properties();
		properties.load(new FileReader("conf/info.properties"));
		String memberClassName = properties.getProperty("memberClassName");
		Class class4 = Class.forName(memberClassName);
		System.out.println(class4);
		/**
		 * 注意：newInstance()方法在创建对象时，只能调用对象的无参构造函数。
		 * (没有无参构造函数报InstantiationException错误)
		 * (没有权限访问（私有化了）无参构造函数报IllegalAccessException错误)
		 * 4.利用Class对象，去实例化一个类对象
		 */
		Object instance =  class3.newInstance();
		System.out.println(instance.toString());
		/**
		 * 5.利用Class对象，获取类的所有构造函数
		 */
		Constructor[] constructors = class3.getConstructors();
		for(Constructor cont:constructors){
			System.out.println(cont);
		}
		/**
		 * 6.利用Class对象，获取带参数的构造函数，然后用newInstance创建有参数对象
		 */
		@SuppressWarnings("unchecked")
		Constructor constructor = class3.getConstructor(String.class,String.class,double.class);
		Object instance2 = constructor.newInstance("xiaolang","doword",7.0);
		System.out.println(instance2.toString());
		System.out.println(class1.getClassLoader());
		System.out.println(class2.getClassLoader());
		System.out.println(class3.getClassLoader());
		getTest(Member.class, "测试：");
	}
	
	
	public static void getTest(Class<?> classz,String string){
		System.out.println(classz);
		System.out.println(classz.getName());
	}
}
